﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Claims;
using System.Text;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Caching.Memory;
using Newtonsoft.Json;
using NLog;
using Org.BouncyCastle.X509;
using SealManagement.Common;
using SealManagement.Extensions;
using SealManagement.Models;
using SealManagement.SqlData;

namespace SealManagement.Controllers
{
    [Authorize(Roles = "User")]
    public class SignMakerController : Controller
    {
        private readonly IMemoryCache _memoryCache;
        private SignContext _context;
        private static Logger logger = LogManager.GetCurrentClassLogger();
        private int usertype = (int)userType.User;
        public SignMakerController(SignContext context, IMemoryCache memoryCache)
        {
            _context = context;
            _memoryCache = memoryCache;
        }
        /// <summary>
        /// 显示用户列表
        /// </summary>
        /// <returns>返回用户列表界面</returns>
        //public async Task<IActionResult> Index()
        //{
        //    X509CertificateParser certificateParser = new X509CertificateParser();

        //    var users = await _context.SignMakers.Where(p => p.IsDelete == 0).ToListAsync() ?? null;
        //    var data = users.Select(s =>
        //    {
        //        //微软自带X509Certificate不认同项目中UKey，需要转为Org.BouncyCastle.X509.X509Certificate类型
        //        Org.BouncyCastle.X509.X509Certificate cert =
        //            certificateParser.ReadCertificate(Convert.FromBase64String(s.Certificator));
        //        return new SignMakerInfo()
        //        {
        //            SignMaker = s,
        //            Issuer = cert.IssuerDN.ToString(),
        //            Subject = cert.SubjectDN.ToString(),
        //            NotBefore = cert.NotBefore.ToString("yyyy-MM-dd HH:mm:ss"),
        //            NotAfter = cert.NotAfter.ToString("yyyy-MM-dd HH:mm:ss"),
        //        };
        //    });
        //    return View(data);
        //}
        public async Task<IActionResult> Index()
        {
            var guid = Guid.NewGuid();
            ViewData["ValidateCode"] = guid.ToString();
            HttpContext.Response.Cookies.Append("ValidateCode",
                Convert.ToBase64String(ToolClass.Encrypt(Encoding.UTF8.GetBytes(guid.ToString()))));
            return View();
        }
        [HttpPost]
        public async Task<IActionResult> Index(int PageSize = 10, int PageIndex = 1)
        {
            X509CertificateParser certificateParser = new X509CertificateParser();

            var users = await _context.SignMakers.Where(p => p.IsDelete == 0).Skip(PageSize * (PageIndex - 1)).Take(PageSize).ToListAsync() ?? null;
            var data = users.Select(s =>
            {
                //微软自带X509Certificate不认同项目中UKey，需要转为Org.BouncyCastle.X509.X509Certificate类型
                Org.BouncyCastle.X509.X509Certificate cert =
                certificateParser.ReadCertificate(Convert.FromBase64String(s.Certificator));
                return new SignMakerInfo()
                {
                    SignMaker = s,
                    Issuer = cert.IssuerDN.ToString(),
                    Subject = cert.SubjectDN.ToString(),
                    NotBefore = cert.NotBefore.ToString("yyyy-MM-dd HH:mm:ss"),
                    NotAfter = cert.NotAfter.ToString("yyyy-MM-dd HH:mm:ss"),
                };
            });
            var total = await _context.SignMakers.Where(p => p.IsDelete == 0).CountAsync();
            logger.Info($"获取制章人信息：获取成功");
            return Json(new { state = resultType.Success, data = data, total = total });
        }

        /// <summary>
        /// 显示单个用户详细信息
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public async Task<IActionResult> Detail(string EncryptData)
        {
            if (!Define.IsChecked)
            {
                logger.Info($"显示制章人详情：获取失败|系统未经自检，请先执行自检后操作");
                return Json(new { state = resultType.Error, message = "系统未经自检，请先执行自检后操作" });
            }
            var jsonBack = ToolClass.EncryptTransit(EncryptData);
            //if (string.IsNullOrEmpty(jsonBack))
            //{
            //    return Json(new { state = resultType.Error, message = "参数错误" });
            //}
            if (int.TryParse(jsonBack, out var errorCodeValue))
            {
                var errorCode = (ErrorCode)errorCodeValue;
                logger.Info($"显示制章人详情：获取失败|错误码：{errorCodeValue}，错误信息：{ToolClass.GetDescription(errorCode)}");
                return Json(new { state = resultType.Error, message = $"错误码：{errorCodeValue}，错误信息：{ToolClass.GetDescription(errorCode)}" });
            }
            var EditModel = JsonConvert.DeserializeObject<EditModel>(jsonBack);
            if (EditModel == null)
            {
                logger.Info($"显示制章人详情：获取失败|数据不存在");
                return Json(new { state = resultType.Error, message = "数据不存在" });
            }

            var user = await _context.SignMakers.Where(u => u.Id == EditModel.Id).FirstAsync();
            X509CertificateParser certificateParser = new X509CertificateParser();
            Org.BouncyCastle.X509.X509Certificate cert =
                    certificateParser.ReadCertificate(Convert.FromBase64String(user.Certificator));
            var data = new SignMakerInfo()
            {
                SignMaker = user,
                Issuer = cert.IssuerDN.ToString(),
                Subject = cert.SubjectDN.ToString(),
                NotBefore = cert.NotBefore.ToString("yyyy-MM-dd HH:mm:ss"),
                NotAfter = cert.NotAfter.ToString("yyyy-MM-dd HH:mm:ss"),
            };
            logger.Info($"显示制章人详情：获取成功|UserID:{user.ArrayNo}");
            //return View(data);
            _memoryCache.Set("UserModelForSignMakerDetail", data);
            return Json(new { state = resultType.Success, data = data });
        }

        public async Task<IActionResult> DetailForViewShow()
        {
            return View("Detail", _memoryCache.Get("UserModelForSignMakerDetail") as SignMakerInfo);
        }
        //public async Task<IActionResult> Details(int id)
        //{
        //    var user = await _context.SignMakers.Where(u => u.Id == id).FirstAsync();
        //    X509CertificateParser certificateParser = new X509CertificateParser();
        //    Org.BouncyCastle.X509.X509Certificate cert =
        //            certificateParser.ReadCertificate(Convert.FromBase64String(user.Certificator));
        //    var data = new SignMakerInfo()
        //    {
        //        SignMaker = user,
        //        Issuer = cert.IssuerDN.ToString(),
        //        Subject = cert.SubjectDN.ToString(),
        //        NotBefore = cert.NotBefore.ToString("yyyy-MM-dd HH:mm:ss"),
        //        NotAfter = cert.NotAfter.ToString("yyyy-MM-dd HH:mm:ss"),
        //    };
        //    return Json(new { state = resultType.Success, data = data});
        //}
        /// <summary>
        /// 创建一个新用户
        /// </summary>
        /// <returns></returns>
        public IActionResult Create()
        {
            var guid = Guid.NewGuid();
            ViewData["ValidateCode"] = guid.ToString();
            HttpContext.Response.Cookies.Append("ValidateCode",
                Convert.ToBase64String(ToolClass.Encrypt(Encoding.UTF8.GetBytes(guid.ToString()))));
            return View();
        }

        /// <summary>
        /// 创建一个新用户
        /// </summary>
        /// <param name="UserModel"></param>
        /// <returns></returns>
        [HttpPost]
        //public async Task<IActionResult> Create([FromBody]SignMaker UserModel)
        public async Task<IActionResult> Create(string EncryptData)
        {
            if (!Define.IsChecked)
            {
                logger.Info($"新增制章人：获取失败|系统未经自检，请先执行自检后操作");
                return Json(new { state = resultType.Error, message = "系统未经自检，请先执行自检后操作" });
            }
            var jsonBack = ToolClass.EncryptTransit(EncryptData);
            //if (string.IsNullOrEmpty(jsonBack))
            //{
            //    return Json(new { state = resultType.Error, message = "参数错误" });
            //}
            if (int.TryParse(jsonBack, out var errorCodeValue))
            {
                var errorCode = (ErrorCode)errorCodeValue;
                logger.Info($"新增制章人：获取失败|错误码：{errorCodeValue}，错误信息：{ToolClass.GetDescription(errorCode)}");
                return Json(new { state = resultType.Error, message = $"错误码：{errorCodeValue}，错误信息：{ToolClass.GetDescription(errorCode)}" });
            }
            var signMakerViewModel = JsonConvert.DeserializeObject<SignMakerViewModel>(jsonBack);
            if (signMakerViewModel == null)
            {
                logger.Info($"新增制章人：获取失败|数据不存在");
                return Json(new { state = resultType.Error, message = "数据不存在" });
            }
            #region cookie验证
            var guidStr = "";
            if (!HttpContext.Request.Cookies.TryGetValue("ValidateCode", out guidStr))
            {
                logger.Info($"新增制章人：获取失败|cookie未设置，请联系管理员");
                return Json(new { state = resultType.Error, message = "cookie未设置，请联系管理员" });
            }
            var guidFromCookie = Encoding.UTF8.GetString(ToolClass.Decrypt(Convert.FromBase64String(guidStr)));
            if (!string.Equals(guidFromCookie, signMakerViewModel.ValidateCode, StringComparison.OrdinalIgnoreCase))
            {
                logger.Info($"新增制章人：获取失败|cookie不正确，请刷新页面后重试");
                return Json(new { state = resultType.Error, message = "cookie不正确，请刷新页面后重试" });
            }
            #endregion
            var signMaker = signMakerViewModel.SignMaker;
            var arrayno = signMaker.ArrayNo;
            var signmaker = _context.SignMakers.Count() == 0 ? null : await _context.SignMakers.FirstOrDefaultAsync(p => p.ArrayNo == arrayno && p.IsDelete == 0);
            if (signmaker != null)
            {
                logger.Info($"新增制章人：获取失败|已存在当前证书|UserID:{signmaker.ArrayNo}");
                return Json(new
                {
                    state = resultType.Error,
                    message = "已存在当前证书",
                    data = signmaker
                });
            }
            var user = _context.Users.Count() == 0 ? null : await _context.Users.FirstOrDefaultAsync(p => p.ArrayNo == arrayno && p.IsDelete == 0);
            if (user != null)
            {
                logger.Info($"新增制章人：获取失败|已存在当前证书|UserID:{user.ArrayNo}");
                return Json(new
                {
                    state = resultType.Error,
                    message = "已存在当前证书",
                    data = user
                });
            }
            var userNew = new SignMaker()
            {
                UserName = signMaker.UserName,
                ArrayNo = signMaker.ArrayNo,
                Certificator = signMaker.Certificator,
                CreateDate = DateTime.Now.ToString(),
                Remark = signMaker.Remark ?? "",
                IsDelete = 0
            };
            _context.Add(userNew);
            int res = await _context.SaveChangesAsync();
            if (res > 0)
            {
                logger.Info($"{User.Identity.Name}创建了新制章人{userNew.UserName}");
                _context.InfoLogs.Add(new InfoLog()
                {
                    UserId = Convert.ToInt32(User.FindFirst(ClaimTypes.Sid).Value),
                    UserName = User.Identity.Name ?? "",
                    CreateDate = DateTime.Now.ToString(),
                    UserType = (int)userType.User,
                    Remark = $"{User.Identity.Name ?? ""}创建了新制章人{userNew.UserName}",
                    ManageType = manageType.AddSignMaker.ToString()
                });
            }
            _context.SaveChanges();
            logger.Info($"新增制章人：获取成功|UserID:{userNew.ArrayNo}");
            return Json(new { state = resultType.Success, message = "成功添加制章人", data = userNew });
        }

        /// <summary>
        /// 编辑用户信息
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public async Task<IActionResult> Edit(string EncryptData)
        {
            if (!Define.IsChecked)
            {
                return Json(new { state = resultType.Error, message = "系统未经自检，请先执行自检后操作" });
            }
            var jsonBack = ToolClass.EncryptTransit(EncryptData);
            if (string.IsNullOrEmpty(jsonBack))
            {
                return Json(new { state = resultType.Error, message = "参数错误" });
            }
            var editModel = JsonConvert.DeserializeObject<EditModel>(jsonBack);
            if (editModel == null)
            {
                return Json(new { state = resultType.Error, message = "数据不存在" });
            }

            var user = await _context.SignMakers.Where(u => u.Id == editModel.Id).FirstAsync();
            _memoryCache.Set("UserModelForSignMaker", user);
            return Json(new { state = resultType.Success, data = user });
        }

        public async Task<IActionResult> EditForViewShow()
        {
            var guid = Guid.NewGuid();
            ViewData["ValidateCode"] = guid.ToString();
            HttpContext.Response.Cookies.Append("ValidateCode",
                Convert.ToBase64String(ToolClass.Encrypt(Encoding.UTF8.GetBytes(guid.ToString()))));
            return View("Edit", _memoryCache.Get("UserModelForSignMaker") as SignMaker);
        }

        //public async Task<IActionResult> Edits(int id)
        //{
        //    var user = await _context.SignMakers.Where(u => u.Id == id).FirstAsync();
        //    return Json(new { state = resultType.Success, data = user }); 
        //}
        /// <summary>
        /// 编辑用户信息
        /// </summary>
        /// <param name="user"></param>
        /// <returns></returns>
        [HttpPost]
        public async Task<IActionResult> EditForSignMaker(string EncryptData)
        {
            if (!Define.IsChecked)
            {
                logger.Info($"修改制章人：操作失败|系统未经自检，请先执行自检后操作");
                return Json(new { state = resultType.Error, message = "系统未经自检，请先执行自检后操作" });
            }
            var jsonBack = ToolClass.EncryptTransit(EncryptData);
            //if (string.IsNullOrEmpty(jsonBack))
            //{
            //    return Json(new { state = resultType.Error, message = "参数错误" });
            //}
            if (int.TryParse(jsonBack, out var errorCodeValue))
            {
                var errorCode = (ErrorCode)errorCodeValue;
                logger.Info($"修改制章人：操作失败|错误码：{errorCodeValue}，错误信息：{ToolClass.GetDescription(errorCode)}");
                return Json(new { state = resultType.Error, message = $"错误码：{errorCodeValue}，错误信息：{ToolClass.GetDescription(errorCode)}" });
            }
            var signMakerViewModel = JsonConvert.DeserializeObject<SignMakerViewModel>(jsonBack);
            if (signMakerViewModel == null)
            {
                logger.Info($"修改制章人：操作失败|数据不存在");
                return Json(new { state = resultType.Error, message = "数据不存在" });
            }
            #region cookie验证
            var guidStr = "";
            if (!HttpContext.Request.Cookies.TryGetValue("ValidateCode", out guidStr))
            {
                logger.Info($"修改制章人：操作失败|cookie未设置，请联系管理员");
                return Json(new { state = resultType.Error, message = "cookie未设置，请联系管理员" });
            }
            var guidFromCookie = Encoding.UTF8.GetString(ToolClass.Decrypt(Convert.FromBase64String(guidStr)));
            if (!string.Equals(guidFromCookie, signMakerViewModel.ValidateCode, StringComparison.OrdinalIgnoreCase))
            {
                logger.Info($"修改制章人：操作失败|cookie不正确，请刷新页面后重试");
                return Json(new { state = resultType.Error, message = "cookie不正确，请刷新页面后重试" });
            }
            #endregion
            var user = signMakerViewModel.SignMaker;
            var signMaker = _context.SignMakers.Single(p => p.Id == user.Id);
            var username = user.UserName == null ? "" : user.UserName.Trim();
            var remark = user.Remark == null ? "" : user.Remark.Trim();
            if (username == "")
            {
                logger.Info($"修改制章人：操作失败|用户名不能为空");
                return Json(new { state = resultType.Error, message = "用户名不能为空" });
            }
            var existSignMaker = _context.Users.FirstOrDefault(s => s.UserName == username);
            if ((existSignMaker != null) && (existSignMaker.Id != user.Id))
                if (_context.SignMakers.FirstOrDefault(s => s.UserName == username) != null)
                {
                    logger.Info($"修改制章人：操作失败|已存在该用户名|{username}");
                    return Json(new { state = resultType.Error, message = "已存在该用户名" });
                }
            signMaker.UserName = username;
            signMaker.Remark = remark;
            int res = await _context.SaveChangesAsync();
            if (res > 0)
            {
                _context.InfoLogs.Add(new InfoLog()
                {
                    UserId = Convert.ToInt32(User.FindFirst(ClaimTypes.Sid).Value),
                    UserName = User.Identity.Name,
                    CreateDate = DateTime.Now.ToString(),
                    UserType = (int)userType.User,
                    Remark = $"{User.Identity.Name}编辑了制章人{username}的信息",
                    ManageType = manageType.EditSignMaker.ToString()
                });
            }
            _context.SaveChanges();
            logger.Info($"修改制章人：操作成功|UserID:{signMaker.ArrayNo}");
            return Json(new { state = resultType.Success, data = user });
        }

        /// <summary>
        /// 删除用户
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public async Task<IActionResult> Delete(string EncryptData)
        {
            if (!Define.IsChecked)
            {
                logger.Info($"删除制章人：操作失败|系统未经自检，请先执行自检后操作");
                return Json(new { state = resultType.Error, message = "系统未经自检，请先执行自检后操作" });
            }
            var jsonBack = ToolClass.EncryptTransit(EncryptData);
            //if (string.IsNullOrEmpty(jsonBack))
            //{
            //    return Json(new { state = resultType.Error, message = "参数错误" });
            //}
            if (int.TryParse(jsonBack, out var errorCodeValue))
            {
                var errorCode = (ErrorCode)errorCodeValue;
                logger.Info($"删除制章人：操作失败|错误码：{errorCodeValue}，错误信息：{ToolClass.GetDescription(errorCode)}");
                return Json(new { state = resultType.Error, message = $"错误码：{errorCodeValue}，错误信息：{ToolClass.GetDescription(errorCode)}" });
            }
            var editModel = JsonConvert.DeserializeObject<EditModel>(jsonBack);
            if (editModel == null)
            {
                logger.Info($"删除制章人：操作失败|数据不存在");
                return Json(new { state = resultType.Error, message = "数据不存在" });
            }
            #region cookie验证
            var guidStr = "";
            if (!HttpContext.Request.Cookies.TryGetValue("ValidateCode", out guidStr))
            {
                logger.Info($"删除制章人：操作失败|cookie未设置，请联系管理员");
                return Json(new { state = resultType.Error, message = "cookie未设置，请联系管理员" });
            }
            var guidFromCookie = Encoding.UTF8.GetString(ToolClass.Decrypt(Convert.FromBase64String(guidStr)));
            if (!string.Equals(guidFromCookie, editModel.ValidateCode, StringComparison.OrdinalIgnoreCase))
            {
                logger.Info($"删除制章人：操作失败|cookie不正确，请刷新页面后重试");
                return Json(new { state = resultType.Error, message = "cookie不正确，请刷新页面后重试" });
            }
            #endregion
            var user = _context.SignMakers.Single(p => p.Id == editModel.Id);
            user.IsDelete = 1;
            int res = await _context.SaveChangesAsync();
            if (res > 0)
            {
                _context.InfoLogs.Add(new InfoLog()
                {
                    UserId = Convert.ToInt32(User.FindFirst(ClaimTypes.Sid).Value),
                    UserName = User.Identity.Name,
                    CreateDate = DateTime.Now.ToString(),
                    UserType = (int)userType.User,
                    Remark = $"{User.Identity.Name}删除了用户{user.UserName}的信息",
                    ManageType = manageType.DelSignMaker.ToString()
                });
            }
            _context.SaveChanges();
            logger.Info($"删除制章人：操作成功|UserID:{user.ArrayNo}");
            return Json(new { state = resultType.Success, message = "成功删除制章人" });
        }

        public async Task<IActionResult> DownCert(string EncryptData)
        {
            if (!Define.IsChecked)
            {
                return Json(new { state = resultType.Error, message = "系统未经自检，请先执行自检后操作" });
            }
            //.cer文件
            var jsonBack = ToolClass.EncryptTransit(EncryptData);
            //if (string.IsNullOrEmpty(jsonBack))
            //{
            //    return Json(new { state = resultType.Error, message = "参数错误" });
            //}
            if (int.TryParse(jsonBack, out var errorCodeValue))
            {
                var errorCode = (ErrorCode)errorCodeValue;
                return Json(new { state = resultType.Error, message = $"错误码：{errorCodeValue}，错误信息：{ToolClass.GetDescription(errorCode)}" });
            }
            var editModel = JsonConvert.DeserializeObject<EditModel>(jsonBack);
            if (editModel == null)
            {
                return Json(new { state = resultType.Error, message = "数据不存在" });
            }
            var user = _context.SignMakers.Single(p => p.Id == editModel.Id);
            var certBytes = Convert.FromBase64String(user.Certificator);
            logger.Info($"{User.Identity.Name}下载了证书");
            _context.InfoLogs.Add(new InfoLog()
            {
                UserId = Convert.ToInt32(User.FindFirst(ClaimTypes.Sid).Value),
                UserName = User.Identity.Name,
                CreateDate = DateTime.Now.ToString(),
                UserType = (int)usertype,
                Remark = $"{User.Identity.Name}下载了证书",
                ManageType = manageType.DownLoadFile.ToString()
            });
            await _context.SaveChangesAsync();
            return File(certBytes, "text/plain", $"Cert_{user.Id}.cer");//文本mime
        }
    }
}